typedef int Semaphore;
typedef int BinarySemaphore;
typedef void* PCB;

void wait(Semaphore s);
void signal(Semaphore s);
#ifndef BARBER
#define n 10
// 其中，costumers不是二进制信号量，因为可能有多个顾客
Semaphore mutex = 1, barber = 1, costumers = 0;
int freeChair = n;

/**
 * 理发师进程 
 */
void Barber()
{
    while (1)
    {
        wait(costumers); // 等待客人，如果没有就睡觉
        // 客人来到
        wait(mutex);    // 临界区保护
        freeChair++;    // barber起身，空出一个座位
        signal(mutex);  // 临界区结束
        signal(barber); // 理发师去剪发
        cutHair();      // 给顾客剪头
    }
}

/**
 * 顾客进程 
 */
void Costomers()
{
    while (1)
    {
        wait(mutex);
        // 对freeChair的判断值也可能因为多进程而不准确
        // 所以用mutex保护
        if (freeChair > 0)
        {
            freeChair--;
            signal(mutex);     // 完成临界区
            signal(costumers); // 此时顾客已经到来
            wait(barber);      // 等待理发师剪头
            haveHairCut();     //顾客被剪头
        }
        else
        {
            signal(mutex); // 退出临界区，没空位走了
        }
    }
}
#endif

void wait(BinarySemaphore bs);
void signal(BinarySemaphore bs);
#ifndef SEM_MUTEX
struct S{
    int val;               // init k
    BinarySemaphore sem;   // init 0,用于对等待S时的排队同步
    int waitCount;         // init 0,表示在S上等待的进程的数量
    BinarySemaphore mutex; //init 1，用于保护对waitCount和val的更新
};

// wait操作
void wait(struct S s){
    wait(s.mutex);// 保护val和waitCount
    if (s.val == 0){// 目前没有空闲，val=0
        s.waitCount++; // 等待的进程增加
        signal(s.mutex); // 退出临界区
        wait(s.sem); // 等待有进程完成了对S的操作，signal掉了sem
    }
    else{
        s.val--;
        signal(s.mutex); // 退出临界区
    }
}

void signal(struct S s){
    wait(s.mutex);// 同样是保护两个数值
    if(s.waitCount>0){
        s.waitCount--;
        signal(s.sem); // 从相当于从等待sem的进程中挑一个执行
    }
    else{
        s.val--;
        // 这里根本就没有等待的进程，因此也不需要signal(s.sem)
    }
    signal(s.mutex);// 最终释放保护信号量
}

#endif // !SEM_MUTEX


#ifndef MONITOR
// 用于实现管程的基本同步手段,他们为整个管程的共享变量

BinarySemaphore next/*init 0*/,mutex/*init 1*/;
int next_count=0;

struct ConditionVariable{

    // CV使用的，实现定制化同步的手段，l
    Semaphore x_sem = 0;
    int x_count = 0;
    PCB wait_queue; // 指向进程的队列

    void wait(){// 其中的操作应当是原子性的
        x_count++;
        if(next_count>0){
            signal(next);
        }
        else{
            signal(mutex);
        }
        wait(x_sem);
        x_count--;
    }

    void signal(){
        if(x_count>0){
            next_count++;
            signal(x_sem);
            wait(next);
            next_count--;
        }
    }
};

#endif // !MONITOR



int main(int argc, char const *argv[]){

}
